module GraphicsModule
  implicit none

! 坐标结构
  type :: FCPoint
    real :: x! 横坐标
    real :: y! 纵坐标
  end type FCPoint

! 大小结构
  type :: FCSize
    real :: cx! 长
    real :: cy! 宽
  end type FCSize

! 矩形结构
  type :: FCRect
    real :: left! 左侧
    real :: top! 上侧
    real :: right! 右侧
    real :: bottom! 底部
  end type FCRect

! 边距信息
  type :: FCPadding
    real :: left! 左侧
    real :: top! 上侧
    real :: right! 右侧
    real :: bottom! 底部
  end type FCPadding

! 绘图结构
  type :: FCPaint
    logical :: cancelClick! 是否退出点击
    character(len=*), parameter :: defaultUIStyle = "light"! 默认样式
    type(FCPoint) :: dragBeginPoint! 拖动开始时的触摸位置
    type(FCRect) :: dragBeginRect! 拖动开始时的区域
    integer :: draggingView! 正被拖动的视图
    integer :: editingTextBox! 正在编辑的文本框
    logical :: firstTouch
    integer :: focusedView! 焦点视图
    logical :: isDoubleClick! 是否双击
    logical :: isMobile
    logical :: isPath! 是否路径
    real :: lastClickTime! 上次点击时间
    logical :: moveTo
    real :: offsetX! 横向偏移
    real :: offsetY! 纵向偏移
    real :: ratio! 缩放比例
    real :: resizeColumnState! 改变列宽度的状态
    real :: resizeColumnBeginWidth! 改变列宽度的起始值
    integer :: resizeColumnIndex! 改变列宽度的索引
    real :: scaleFactorX! 横向缩放比例
    real :: scaleFactorY! 纵向缩放比例
    logical :: secondTouch
    character(len=*), parameter :: systemFont = "Arial"! 系统字体
    type(FCPoint) :: touchDownPoint
    type(FCPoint) :: touchFirstPoint
    type(FCPoint) :: touchSecondPoint
    integer :: touchDownView! 鼠标按下的视图
    integer :: touchMoveView! 鼠标移动的视图
    integer, allocatable :: views(:)! 

   ! 添加线
    contains
    subroutine addLine(this, x1, y1, x2, y2)
      class(FCPaint), intent(inout) :: this
      real, intent(in) :: x1, y1, x2, y2
    end subroutine addLine

   ! 开始路径
    subroutine beginPath(this)
      class(FCPaint), intent(inout) :: this
    end subroutine beginPath

   ! 开始绘图
    subroutine beginPaint(this, rect)
      class(FCPaint), intent(inout) :: this
      type(FCRect), intent(in) :: rect
    end subroutine beginPaint

   ! 闭合路径
    subroutine closeFigure(this)
      class(FCPaint), intent(inout) :: this
    end subroutine closeFigure

   ! 关闭路径
    subroutine closePath(this)
      class(FCPaint), intent(inout) :: this
    end subroutine closePath

   ! 绘制线
    subroutine drawLine(this, color, width, style, x1, y1, x2, y2)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
      real, intent(in) :: width
      integer, intent(in) :: style(:)
      real, intent(in) :: x1, y1, x2, y2
    end subroutine drawLine

   ! 绘制路径
    subroutine drawPath(this, color, width, style)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
      real, intent(in) :: width
      integer, intent(in) :: style(:)
    end subroutine drawPath

   ! 绘制连续线条
    subroutine drawPolyline(this, color, width, style, apt)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
      real, intent(in) :: width
      integer, intent(in) :: style(:)
      type(FCPoint), intent(in) :: apt(:)
    end subroutine drawPolyline

   ! 绘制多边形
    subroutine drawPolygon(this, color, width, style, apt)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
      real, intent(in) :: width
      integer, intent(in) :: style(:)
      type(FCPoint), intent(in) :: apt(:)
    end subroutine drawPolygon

   ! 绘制图片
    subroutine drawImage(this, image, left, top, right, bottom)
      class(FCPaint), intent(inout) :: this
      integer, intent(in) :: image
      real, intent(in) :: left, top, right, bottom
    end subroutine drawImage

   ! 绘制矩形
    subroutine drawRect(this, color, width, style, left, top, right, bottom)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
      real, intent(in) :: width
      integer, intent(in) :: style(:)
      real, intent(in) :: left, top, right, bottom
    end subroutine drawRect

   ! 绘制椭圆
    subroutine drawEllipse(this, color, width, style, left, top, right, bottom)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
      real, intent(in) :: width
      integer, intent(in) :: style(:)
      real, intent(in) :: left, top, right, bottom
    end subroutine drawEllipse

   ! 绘制圆角矩形
    subroutine drawRoundRect(this, color, width, style, left, top, right, bottom, cornerRadius)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
      real, intent(in) :: width
      integer, intent(in) :: style(:)
      real, intent(in) :: left, top, right, bottom
      real, intent(in) :: cornerRadius
    end subroutine drawRoundRect

   ! 绘制文字
    subroutine drawText(this, text, color, font, x, y)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: text
      character(len=*), intent(in) :: color
      character(len=*), intent(in) :: font
      real, intent(in) :: x, y
    end subroutine drawText

   ! 结束绘图
    subroutine endPaint(this)
      class(FCPaint), intent(inout) :: this
    end subroutine endPaint

   ! 填充路径
    subroutine fillPath(this, color)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
    end subroutine fillPath

   ! 填充多边形
    subroutine fillPolygon(this, color, apt)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
      type(FCPoint), intent(in) :: apt(:)
    end subroutine fillPolygon

   ! 填充矩形
    subroutine fillRect(this, color, left, top, right, bottom)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
      real, intent(in) :: left, top, right, bottom
    end subroutine fillRect

   ! 填充圆角矩形
    subroutine fillRoundRect(this, color, left, top, right, bottom, cornerRadius)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
      real, intent(in) :: left, top, right, bottom
      real, intent(in) :: cornerRadius
    end subroutine fillRoundRect

   ! 填充椭圆
    subroutine fillEllipse(this, color, left, top, right, bottom)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: color
      real, intent(in) :: left, top, right, bottom
    end subroutine fillEllipse

   ! 裁剪
    subroutine setClip(this, left, top, right, bottom)
      class(FCPaint), intent(inout) :: this
      real, intent(in) :: left, top, right, bottom
    end subroutine setClip

   ! 设置偏移量
    subroutine setOffset(this, x, y)
      class(FCPaint), intent(inout) :: this
      real, intent(in) :: x, y
      this%offsetX = x
      this%offsetY = y
    end subroutine setOffset

   ! 获取字体大小
    function textSize(this, text, font) result(res)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: text
      character(len=*), intent(in) :: font
      type(FCSize) :: res
      res%cx = 0.0
      res%cy = 0.0
    end function textSize

   ! 保存状态
    subroutine save(this)
      class(FCPaint), intent(inout) :: this
    end subroutine save

   ! 恢复状态
    subroutine restore(this)
      class(FCPaint), intent(inout) :: this
    end subroutine restore

   ! 绘制自动省略文字
    subroutine drawTextAutoEllipsis(this, text, color, font, left, top, right, bottom)
      class(FCPaint), intent(inout) :: this
      character(len=*), intent(in) :: text
      character(len=*), intent(in) :: color
      character(len=*), intent(in) :: font
      real, intent(in) :: left, top, right, bottom
      integer :: tSize(2), subLen, newLen
      logical :: flag
      if (len_trim(text) > 0) then
        tSize = this%textSize(text, font)
        if (tSize(1) < right - left) then
          call this%drawText(text, color, font, left, top)
        else
          if (tSize(1) > 0) then
            subLen = 3
            flag =.true.
            do while (flag)
              newLen = len(text) - subLen
              if (newLen > 0) then
               ! 构造省略后的文字
                character(len=:), allocatable :: newText
                newText = text(1:newLen) // "..."
                tSize = this%textSize(newText, font)
                if (tSize(1) < right - left) then
                  call this%drawText(newText, color, font, left, top)
                  flag =.false.
                else
                  subLen = subLen + 3
                end if
              else
                flag =.false.
              end if
            end do
          end if
        end if
      end if
    end subroutine drawTextAutoEllipsis
  end type FCPaint
end module GraphicsModule

module ViewModule
  use GraphicsModule! 
  implicit none

 ! 基础视图
  type :: FCView
    logical :: allowDrag! 是否允许拖动
    logical :: allowResize! 是否可以拖动改变大小
    character(len=*), parameter :: align = "left"! 横向布局
    logical :: allowDragScroll! 是否允许拖动滚动
    logical :: allowPreviewsEvent! 是否允许预处理事件
    character(len=*), parameter :: backColor = "rgb(255,255,255)"! 背景色
    character(len=*), parameter :: borderColor = "rgb(150,150,150)"! 边线色
    real :: borderWidth! 边线宽度
    type(FCRect) :: clipRect! 裁剪区域
    real :: cornerRadius! 圆角
    character(len=*), parameter :: cursor = ""! 光标
    logical :: downScrollHButton! 是否按下横向滚动条
    logical :: downScrollVButton! 是否按下纵向滚动条
    logical :: displayOffset! 是否显示偏移量
    character(len=*), parameter :: dock = "none"! 悬浮状态
    logical :: enabled! 是否可用
    character(len=*), parameter :: font = "Default,12"! 字体
    character(len=*), parameter :: hoveredColor = ""! 鼠标悬停时的颜色
    logical :: hoverScrollHButton! 是否悬停横向滚动条
    logical :: hoverScrollVButton! 是否悬停纵向滚动条
    logical :: hScrollIsVisible! 横向滚动是否显示
    type(FCPoint) :: location! 坐标
    type(FCPadding) :: margin! 外边距
    type(FCSize) :: maximumSize! 最大大小
    type(FCPadding) :: padding! 内边距
    type(FCPaint), pointer :: paint! 绘图对象
    type(FCView), pointer :: parent! 父视图
    real :: resizePoint! 调整尺寸的点
    real :: scrollV! 纵向滚动
    real :: scrollH! 横向滚动
    real :: scrollSize! 滚动条的大小
    logical :: showHScrollBar! 是否显示横向滚动条
    logical :: showVScrollBar! 是否显示横向滚动条
    character(len=*), parameter :: scrollBarColor = "rgb(200,200,200)"! 滚动条的颜色
    character(len=*), parameter :: scrollBarHoveredColor = "rgb(42,138,195)"! 滚动条悬停的颜色
    type(FCSize) :: size! 大小
    real :: startScrollH! 开始滚动的值
    real :: startScrollV! 结束滚动的值
    type(FCPoint) :: startPoint! 起始点
    type(FCRect) :: startRect! 移动开始时的视图矩形
    integer :: tabIndex! Tab索引
    logical :: tabStop! 是否支持Tab
    character(len=*), parameter :: text = ""! 文字
    character(len=*), parameter :: textColor = "rgb(0,0,0)"! 前景色
    character(len=*), parameter :: textAlign = "left"
    logical :: topMost! 是否置顶
    real :: touchDownTime! 鼠标按下的时间
    character(len=*), parameter :: viewName = ""! 名称
    logical :: visible! 可见性
    character(len=*), parameter :: verticalAlign = "top"! 纵向布局
    character(len=*), parameter :: viewType = "none"! 类型
    logical :: vScrollIsVisible! 纵向滚动是否显示
    integer, allocatable :: views(:)!

   ! 构造函数
    contains
    subroutine init(this)
      class(FCView), intent(inout) :: this
     ! 对成员进行初始化
      this%allowDrag =.false.
      this%allowResize =.false.
      this%borderWidth = 1.0
      this%clipRect%left = 0.0
      this%clipRect%top = 0.0
      this%clipRect%right = 0.0
      this%clipRect%bottom = 0.0
      this%cornerRadius = 0.0
      this%downScrollHButton =.false.
      this%downScrollVButton =.false.
      this%displayOffset =.true.
      this%enabled =.true.
      this%hoverScrollHButton =.false.
      this%hoverScrollVButton =.false.
      this%hScrollIsVisible =.false.
      this%input = 0
      this%location%x = 0.0
      this%location%y = 0.0
      this%margin%left = 0.0
      this%margin%top = 0.0
      this%margin%right = 0.0
      this%margin%bottom = 0.0
      this%maximumSize%cx = 0.0
      this%maximumSize%cy = 0.0
      this%padding%left = 0.0
      this%padding%top = 0.0
      this%padding%right = 0.0
      this%padding%bottom = 0.0
      nullify(this%paint)
      nullify(this%parent)
      this%resizePoint = -1.0
      this%scrollV = 0.0
      this%scrollH = 0.0
      this%scrollSize = 8.0
      this%showHScrollBar =.false.
      this%showVScrollBar =.false.
      this%size%cx = 0.0
      this%size%cy = 0.0
      this%startScrollH = 0.0
      this%startScrollV = 0.0
      this%startPoint%x = 0.0
      this%startPoint%y = 0.0
      this%startRect%left = 0.0
      this%startRect%top = 0.0
      this%startRect%right = 0.0
      this%startRect%bottom = 0.0
      this%tabIndex = 0
      this%tabStop =.false.
      this%text = ""
      this%vScrollIsVisible =.false.
      allocate(this%views(0))
    end subroutine init
  end type FCView
end module ViewModule

module ViewFunctionsModule
  use ViewModule
  implicit none

 ! 添加顶层视图
  subroutine addView(this_view, this_paint)
    type(FCView), intent(inout) :: this_view
    type(FCPaint), intent(inout) :: this_paint
    this_view%paint => this_paint
    call pushView(this_paint, this_view)
  end subroutine addView

 ! 将视图添加到绘图对象的视图
  subroutine pushView(paint, view)
    type(FCPaint), intent(inout) :: paint
    type(FCView), intent(in) :: view
    integer :: old_size, new_size
    old_size = size(paint%views)
    new_size = old_size + 1
    allocate(paint%views(new_size))
    paint%views(1:old_size) = paint%views(1:old_size)
    paint%views(new_size) = view
  end subroutine pushView

 ! 添加到父视图
  subroutine addViewToParent(this_view, parent_view)
    type(FCView), intent(inout) :: this_view
    type(FCView), intent(inout) :: parent_view
    this_view%paint => parent_view%paint
    if (.not. allocated(parent_view%views)) then
      allocate(parent_view%views(0))
    end if
    call pushView(parent_view, this_view)
    this_view%parent => parent_view
  end subroutine addViewToParent

 ! 清除视图
  subroutine clearViews(paint)
    type(FCPaint), intent(inout) :: paint
    deallocate(paint%views)
    allocate(paint%views(0))
  end subroutine clearViews

 ! 移除顶层视图
  subroutine removeView(this_view, paint)
    type(FCView), intent(inout) :: this_view
    type(FCPaint), intent(inout) :: paint
    integer :: i, size_views
    logical :: found
    size_views = size(paint%views)
    found =.false.
    do i = 1, size_views
      if (paint%views(i) == this_view) then
        found =.true.
        call removeAtIndex(paint%views, i)
        exit
      end if
    end do
  end subroutine removeView

 ! 从数组中移除指定索引的元素
  subroutine removeAtIndex(array, index)
    type(FCView), allocatable, intent(inout) :: array(:)
    integer, intent(in) :: index
    integer :: new_size, i
    new_size = size(array) - 1
    if (new_size > 0) then
      do i = index, new_size
        array(i) = array(i + 1) 
      end do
      deallocate(array(new_size + 1))
      allocate(array(new_size))
    else
      deallocate(array)
      allocate(array(0))
    end if
  end subroutine removeAtIndex

 ! 从父视图中移除
  subroutine removeViewFromParent(this_view, parent_view)
    type(FCView), intent(inout) :: this_view
    type(FCView), intent(inout) :: parent_view
    integer :: i, size_views
    logical :: found
    size_views = size(parent_view%views)
    found =.false.
    do i = 1, size_views
      if (parent_view%views(i) == this_view) then
        found =.true.
        call removeAtIndex(parent_view%views, i)
        exit
      end if
    end do
  end subroutine removeViewFromParent

 ! 获取绝对位置X
  function clientX(view) result(res)
    type(FCView), intent(in) :: view
    real :: res
    if (associated(view)) then
      res = view%location%x
      if (associated(view%parent)) then
        if (view%parent%displayOffset.and. view%parent%scrollH > 0.0) then
          res = res + clientX(view%parent) - view%parent%scrollH
        else
          res = res + clientX(view%parent)
        end if
      end if
    else
      res = 0.0
    end if
  end function clientX

 ! 获取绝对位置Y
  function clientY(view) result(res)
    type(FCView), intent(in) :: view
    real :: res
    if (associated(view)) then
      res = view%location%y
      if (associated(view%parent)) then
        if (view%parent%displayOffset.and. view%parent%scrollV > 0.0) then
          res = res + clientY(view%parent) - view%parent%scrollV
        else
          res = res + clientY(view%parent)
        end if
      end if
    else
      res = 0.0
    end if
  end function clientY

 ! 是否包含坐标
  function containsPoint(view, mp) result(res)
    type(FCView), intent(in) :: view
    type(FCPoint), intent(in) :: mp
    logical :: res
    real :: clx, cly
    type(FCPoint) :: cp
    type(FCSize) :: size
    if (isViewEnabled(view)) then
      clx = clientX(view)
      cly = clientY(view)
      size = view%size
      cp%x = mp%x - clx
      cp%y = mp%y - cly
      if (cp%x >= 0.0.and. cp%x <= size%cx.and. &
          cp%y >= 0.0.and. cp%y <= size%cy) then
        res =.true.
      else
        res =.false.
      end if
    else
      res =.false.
    end if
  end function containsPoint

 ! 判断视图是否可用
  function isViewEnabled(view) result(res)
    type(FCView), intent(in) :: view
    logical :: res
    res = view%enabled
  end function isViewEnabled

 ! 查找有预处理事件的父视图
  function findPreviewsEventParent(view) result(res)
    type(FCView), intent(in) :: view
    type(FCView), pointer :: res
    if (.not. view%allowPreviewsEvent.and. associated(view%parent)) then
      if (view%parent%allowPreviewsEvent) then
        res => view%parent
      else
        res => findPreviewsEventParent(view%parent)
      end if
    else
      nullify(res)
    end if
  end function findPreviewsEventParent

 ! 根据名称查找视图
  function findViewByName(name, views) result(res)
    character(len=*), intent(in) :: name
    type(FCView), intent(in) :: views(:)
    type(FCView), pointer :: res
    integer :: i, size_views
    size_views = size(views)
    do i = 1, size_views
      if (views(i)%viewName == name) then
        res => views(i)
        return
      else
        if (allocated(views(i)%views)) then
          res => findViewByName(name, views(i)%views)
          if (associated(res)) then
            return
          end if
        end if
      end if
    end do
    nullify(res)
  end function findViewByName

 ! 根据坐标查找视图
  function findView(mp, views) result(res)
    type(FCPoint), intent(in) :: mp
    type(FCView), intent(in) :: views(:)
    type(FCView), pointer :: res
    integer :: i, size_views
    logical :: hasPoint
    size_views = size(views)
    do i = size_views, 1, -1
      if (views(i)%visible.and. views(i)%topMost) then
        hasPoint = containsPoint(views(i), mp)
        if (hasPoint) then
          if (views(i)%vScrollIsVisible.and. views(i)%scrollSize > 0.0) then
            if (mp%x >= clientX(views(i)) + views(i)%size%cx - views(i)%scrollSize) then
              res => views(i)
              return
            end if
          end if
          if (views(i)%hScrollIsVisible.and. views(i)%scrollSize > 0.0) then
            if (mp%y >= clientY(views(i)) + views(i)%size%cy - views(i)%scrollSize) then
              res => views(i)
              return
            end if
          end if
          if (allocated(views(i)%views)) then
            res => findView(mp, views(i)%views)
            if (associated(res)) then
              return
            end if
          end if
          res => views(i)
          return
        end if
      end if
    end do
   ! 再查找非置顶且可见的视图
    do i = size_views, 1, -1
      if (views(i)%visible.and..not. views(i)%topMost) then
        hasPoint = containsPoint(views(i), mp)
        if (hasPoint) then
          if (views(i)%vScrollIsVisible.and. views(i)%scrollSize > 0.0) then
            if (mp%x >= clientX(views(i)) + views(i)%size%cx - views(i)%scrollSize) then
              res => views(i)
              return
            end if
          end if
          if (views(i)%hScrollIsVisible.and. views(i)%scrollSize > 0.0) then
            if (mp%y >= clientY(views(i)) + views(i)%size%cy - views(i)%scrollSize) then
              res => views(i)
              return
            end if
          end if
          if (allocated(views(i)%views)) then
            res => findView(mp, views(i)%views)
            if (associated(res)) then
              return
            end if
          end if
          res => views(i)
          return
        end if
      end if
    end do
    nullify(res)
  end function findView
end module ViewFunctionsModule

module ViewRenderingModule
  use ViewModule
  use ViewFunctionsModule
  implicit none

! 是否重绘时可见
  function isPaintVisible(view) result(res)
    type(FCView), intent(in) :: view
    logical :: res
    if (view%visible) then
      if (associated(view%parent)) then
        if (view%parent%visible) then
          res = isPaintVisible(view%parent)
        else
          res =.false.
        end if
      else
        res =.true.
      end if
    else
      res =.false.
    end if
  end function isPaintVisible

! 是否视图可用
  function isViewEnabled(view) result(res)
    type(FCView), intent(in) :: view
    logical :: res
    if (view%enabled) then
      if (associated(view%parent)) then
        if (view%parent%enabled) then
          res = isViewEnabled(view%parent)
        else
          res =.false.
        end if
      else
        res =.true.
      end if
    else
      res =.false.
    end if
  end function isViewEnabled

! 获取区域的交集
  function getIntersectRect(lpDestRect, lpSrc1Rect, lpSrc2Rect) result(res)
    type(FCRect), intent(inout) :: lpDestRect
    type(FCRect), intent(in) :: lpSrc1Rect
    type(FCRect), intent(in) :: lpSrc2Rect
    integer :: res
    lpDestRect%left = max(lpSrc1Rect%left, lpSrc2Rect%left)
    lpDestRect%right = min(lpSrc1Rect%right, lpSrc2Rect%right)
    lpDestRect%top = max(lpSrc1Rect%top, lpSrc2Rect%top)
    lpDestRect%bottom = min(lpSrc1Rect%bottom, lpSrc2Rect%bottom)
    if (lpDestRect%right > lpDestRect%left.and. lpDestRect%bottom > lpDestRect%top) then
      res = 1
    else
      lpDestRect%left = 0.0
      lpDestRect%right = 0.0
      lpDestRect%top = 0.0
      lpDestRect%bottom = 0.0
      res = 0
    end if
  end function getIntersectRect

! 重绘视图
  subroutine renderViews(views, paint, rect)
    type(FCView), intent(in) :: views(:)
    type(FCPaint), intent(inout) :: paint
    type(FCRect), intent(in) :: rect
    integer :: viewsSize, i, subViewsSize
    type(FCView) :: view
    type(FCRect) :: drawRect, clipRect, destRect

    viewsSize = size(views)
    do i = 1, viewsSize
      view = views(i)
      if (.not. associated(rect)) then
        if (allocated(view%views)) then
          subViewsSize = size(view%views)
          if (subViewsSize > 0) then
            call renderViews(view%views, paint, rect)
          end if
        end if
        nullify(view%clipRect)
        cycle
      end if
      if (.not. view%topMost.and. isPaintVisible(view)) then
        clipRect%left = clientX(view)
        clipRect%top = clientY(view)
        clipRect%right = clipRect%left + view%size%cx
        clipRect%bottom = clipRect%top + view%size%cy
        drawRect%left = 0.0
        drawRect%top = 0.0
        drawRect%right = view%size%cx
        drawRect%bottom = view%size%cy
        destRect%left = 0.0
        destRect%top = 0.0
        destRect%right = 0.0
        destRect%bottom = 0.0
        if (getIntersectRect(destRect, rect, clipRect) > 0) then
          call paint%save()
          call paint%setOffset(0.0, 0.0)
          call paint%setClip(destRect%left, destRect%top, destRect%right, destRect%bottom)
          view%clipRect => destRect
          call paint%setOffset(clipRect%left, clipRect%top)
         ! call fonPaintDefault(view, paint, drawRect)
          if (allocated(view%views)) then
            subViewsSize = size(view%views)
            if (subViewsSize > 0) then
              call renderViews(view%views, paint, destRect)
            end if
          end if
          call paint%setOffset(clipRect%left, clipRect%top)
         ! call onPaintBorderDefault(view, paint, drawRect)
          call paint%restore()
        else
          if (allocated(view%views)) then
            subViewsSize = size(view%views)
            if (subViewsSize > 0) then
              call renderViews(view%views, paint, rect)
            end if
          end if
          nullify(view%clipRect)
        end if
      end if
    end do

    do i = 1, viewsSize
      view = views(i)
      if (.not. associated(rect)) then
        cycle
      end if
      if (view%topMost.and. isPaintVisible(view)) then
        clipRect%left = clientX(view)
        clipRect%top = clientY(view)
        clipRect%right = clipRect%left + view%size%cx
        clipRect%bottom = clipRect%top + view%size%cy
        drawRect%left = 0.0
        drawRect%top = 0.0
        drawRect%right = view%size%cx
        drawRect%bottom = view%size%cy
        destRect%left = 0.0
        destRect%top = 0.0
        destRect%right = 0.0
        destRect%bottom = 0.0
        if (getIntersectRect(destRect, rect, clipRect) > 0) then
          call paint%save()
          call paint%setOffset(0.0, 0.0)
          view%clipRect => destRect
          call paint%setClip(destRect%left, destRect%top, destRect%right, destRect%bottom)
          call paint%setOffset(clipRect%left, clipRect%top)
         ! call onPaintDefault(view, paint, drawRect)
          if (allocated(view%views)) then
            subViewsSize = size(view%views)
            if (subViewsSize > 0) then
              call renderViews(view%views, paint, destRect)
            end if
          end if
          call paint%setOffset(clipRect%left, clipRect%top)
         ! call onPaintBorderDefault(view, paint, drawRect)
          call paint%restore()
        else
          if (allocated(view%views)) then
            subViewsSize = size(view%views)
            if (subViewsSize > 0) then
              call renderViews(view%views, paint, rect)
            end if
          end if
          nullify(view%clipRect)
        end if
      end if
    end do
  end subroutine renderViews

! 全局刷新方法
  subroutine invalidate(paint)
    type(FCPaint), intent(inout) :: paint
  end subroutine invalidate

! 刷新视图
  subroutine invalidateView(view)
    type(FCView), intent(in) :: view
  end subroutine invalidateView
end module ViewRenderingModule